Skip to content

Conversation

@dkslel1225
Copy link
Contributor

@dkslel1225 dkslel1225 commented Jun 20, 2025

📌 변경 사항 개요

  • 카드 수정 모달 구현
  • 아바타 컴포넌트 수정

✨ 요약

📝 상세 내용

payload 목록 타입

  dashboardId: number
  columnId: number
  assigneeUserId: number
  title: string - 필수
  description: string - 필수
  dueDate?: string
  tags: string[]
  imageUrl?: string
  • dashboardId는 인풋값으로 받지 않고, 따로 payload에 추가해서 put 요청 보내게 됨
  • 하나라도 변경사항이 생기면, 수정 버튼 활성화

🔗 관련 이슈

🖼️ 스크린샷

image image
2025-06-20.9.31.03.mov

✅ 체크리스트

  • 브랜치 네이밍 컨벤션을 준수했습니다
  • 커밋 컨벤션을 준수했습니다
  • 코드가 프로젝트의 스타일 가이드라인을 준수합니다

💡 참고 사항

Summary by CodeRabbit

  • 신규 기능

    • 대시보드 초대 및 생성 모달, 카드 수정 폼, 카드 상세 모달 등 다양한 신규 컴포넌트와 글로벌 모달 렌더러가 추가되었습니다.
    • 카드 및 대시보드 관리 기능에 페이지네이션, 태그 삭제, 어사이니(담당자) 선택 등 다양한 인터랙션이 도입되었습니다.
    • 대시보드 삭제 버튼 및 초대 API 연동 등 대시보드 관리 기능이 확장되었습니다.
  • 기능 개선

    • 대시보드, 카드, 멤버, 초대 관리 UI가 개선되고, 일부 컴포넌트가 더 세분화되어 유지보수성이 향상되었습니다.
    • 카드, 대시보드, 멤버 등 주요 데이터의 상태 관리가 전역 스토어 기반으로 일원화되었습니다.
    • 다크 모드 지원 및 반응형 레이아웃, 접근성, 버튼 및 입력 UI가 개선되었습니다.
  • 버그 수정

    • 멤버, 초대, 카드 리스트 등에서 중복 key 및 잘못된 스타일 이슈가 수정되었습니다.
    • 사용자 정보 및 아바타 관련 데이터 처리 방식이 개선되어 예외 상황에 안전하게 동작합니다.
  • 리팩터링 및 스타일

    • 헤더, 사이드바, 드롭다운 등 주요 UI 컴포넌트가 분리 및 리팩터링되어 코드 구조가 명확해졌습니다.
    • Tailwind, CSS 유틸리티 클래스 및 반응형 브레이크포인트가 정비되었습니다.
  • 기타

    • 내부 상태 관리, 타입 분리, API 연동 방식 등 코드 구조가 전반적으로 개선되었습니다.

@coderabbitai
Copy link

coderabbitai bot commented Jun 20, 2025

Walkthrough

이 변경 사항은 대시보드의 카드 수정 및 생성 모달 기능을 대대적으로 확장합니다. 카드 수정 폼, 컬럼/담당자 선택, 태그 삭제, 이미지 업로드, 글로벌 컬럼 스토어 도입, 카드 상세 모달, 다양한 UI 컴포넌트 및 스타일 유틸리티가 추가 및 개선되었습니다.

Changes

파일(들) 변경 요약
src/app/dashboard/[id]/page.tsx, .../Column/Column.tsx 컬럼 데이터 글로벌 스토어 동기화 및 컬럼 prop 전달 방식 변경, 레이아웃 클래스 수정
src/app/features/dashboard_Id/Card/Card.tsx 카드 prop 구조 변경, 카드 상세 모달 기능 추가, 태그/담당자/날짜 렌더링 개선
src/app/features/dashboard_Id/Card/ColumnTitle.tsx, .../MyAssignee.tsx, .../TagsCanDelete.tsx 컬럼명, 담당자, 삭제 가능한 태그 등 신규 UI 컴포넌트 도입
src/app/features/dashboard_Id/Card/Tags.tsx 다크모드 지원 태그 색상 로직 개선
src/app/features/dashboard_Id/Card/cardFormModals/AssigneeList.tsx, .../ColumnList.tsx 담당자/컬럼 리스트 컴포넌트 구조 개선 및 신규 컬럼 리스트 컴포넌트 추가
src/app/features/dashboard_Id/Card/cardFormModals/CreateCardForm.tsx 담당자 선택 UI 및 태그 삭제 기능 개선
.../CreateCardModal.tsx 모달 onClose prop 제거, children만 받도록 변경
.../ModifyCardForm.tsx 카드 수정 폼 신규 구현(폼 상태, 이미지 업로드, 태그 관리 등 포함)
.../input/DateInput.tsx input ref 위치 및 width 스타일 조정
.../cardModal/CardContent.tsx, .../CardModal.tsx 카드 상세 모달 및 카드 상세 콘텐츠 컴포넌트 신규 도입
.../api/putCard.ts, .../usePutCardMutation.ts 카드 수정 API 및 React Query mutation 훅 신규 도입
.../lib/getDashboardMembers.ts 담당자 데이터 구조 변경 및 profileImageUrl 포함
.../store/useColumnsStore.ts 글로벌 컬럼 Zustand 스토어 신규 도입
.../store/useDragStore.ts Card 타입 import 경로 수정
.../type/CardFormData.type.ts 카드 폼 데이터 타입 분리(CardModifyFormData, CardFormData)
src/app/globals.css 다크모드 색상, 새로운 유틸리티 클래스(BG-lightblue, Text-deepblue) 추가 및 일부 스타일 수정
src/app/shared/components/common/Avatar.tsx Avatar 컴포넌트 prop 구조 변경 및 렌더링 로직 개선
tailwind.config.ts Tailwind 브레이크포인트(모바일/태블릿) 재정의 및 데스크탑 제거

Sequence Diagram(s)

sequenceDiagram
  participant User
  participant Card
  participant CardModal
  participant CardContent
  participant ModifyCardForm
  participant API

  User->>Card: 카드 클릭
  Card->>CardModal: CardModal 오픈
  CardModal->>CardContent: 카드 상세 정보 렌더
  User->>CardContent: 수정 버튼 클릭
  CardContent->>ModifyCardForm: 수정 폼 모달 오픈
  User->>ModifyCardForm: 폼 입력(컬럼, 담당자, 태그, 이미지 등)
  User->>ModifyCardForm: 저장 클릭
  ModifyCardForm->>API: putCard API 호출
  API-->>ModifyCardForm: 응답(성공/실패)
  ModifyCardForm->>CardContent: onClose 호출(성공 시)
  CardContent->>CardModal: 모달 닫기
Loading

Possibly related issues

Possibly related PRs

Suggested labels

🎨Style

Suggested reviewers

  • LeeCh0129
  • Insung-Jo

Poem

🐇
카드가 춤추는 대시보드 밤,
모달이 열리고 태그가 빛나네.
담당자 아바타, 컬럼명 반짝,
수정과 생성, 모두 한 번에!
코드도 스타일도 한층 더 새로워,
토끼는 기뻐 깡총깡총 뛰네.
🥕✨

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 ESLint

If the error stems from missing dependencies, add them to the package.json file. For unrecoverable errors (e.g., due to private dependencies), disable the tool in the CodeRabbit configuration.

npm error Exit handler never called!
npm error This is an error with npm itself. Please report this error at:
npm error https://github.com/npm/cli/issues
npm error A complete log of this run can be found in: /.npm/_logs/2025-06-20T12_31_45_911Z-debug-0.log

✨ Finishing Touches
  • 📝 Generate Docstrings

🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Explain this complex logic.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai explain this code block.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and explain its main purpose.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai generate sequence diagram to generate a sequence diagram of the changes in this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

@dkslel1225 dkslel1225 self-assigned this Jun 20, 2025
@dkslel1225 dkslel1225 added ✨Feat 기능 개발 🐛Fix 버그 수정 labels Jun 20, 2025
@dkslel1225 dkslel1225 added this to the 2차 구현 기간 milestone Jun 20, 2025
@dkslel1225 dkslel1225 linked an issue Jun 20, 2025 that may be closed by this pull request
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 13

🧹 Nitpick comments (17)
tailwind.config.ts (1)

21-21: 주석과 구현 간 불일치 수정 필요

주석에는 "376 ~ 1919px"라고 되어 있지만, 실제 구현은 376px에서 744px까지의 범위입니다. 주석을 올바르게 수정해주세요.

-        tablet: { raw: '(min-width: 376px) and (max-width: 744px)' }, // 376 ~ 1919px
+        tablet: { raw: '(min-width: 376px) and (max-width: 744px)' }, // 376 ~ 744px
src/app/features/dashboard_Id/Card/ColumnTitle.tsx (2)

1-1: Props 타입을 별도 인터페이스로 정의 권장

재사용성과 가독성을 위해 props 타입을 별도 인터페이스로 정의하는 것을 고려해보세요.

+interface ColumnTitleProps {
+  title: string
+}
+
-export default function ColumnTitle({ title }: { title: string }) {
+export default function ColumnTitle({ title }: ColumnTitleProps) {

4-4: 스타일 일관성을 위한 커스텀 클래스 사용 권장

하드코딩된 색상값 #228DFF 대신 기존 커스텀 유틸리티 클래스를 사용하여 일관성을 유지하는 것이 좋겠습니다.

-      <div className="size-6 rounded-25 bg-[#228DFF]"></div>
+      <div className="size-6 rounded-25 bg-[#228DFF]"></div>

현재 globals.css에서 같은 색상이 사용되는 다른 클래스들이 있으니 통일된 스타일 클래스를 만드는 것을 고려해보세요.

src/app/features/dashboard_Id/Card/cardModal/CardModal.tsx (1)

12-12: 접근성을 위한 속성 추가 권장

모달의 접근성을 향상시키기 위해 ARIA 속성을 추가하는 것을 고려해보세요.

      <div className="BG-white min-h-764 w-730 overflow-y-scroll rounded-16 p-32 shadow-lg [mask-image:radial-gradient(white_100%,transparent_100%)]">
+      <div 
+        className="BG-white min-h-764 w-730 overflow-y-scroll rounded-16 p-32 shadow-lg [mask-image:radial-gradient(white_100%,transparent_100%)]"
+        role="dialog"
+        aria-modal="true"
+      >
src/app/features/dashboard_Id/api/usePutCardMutation.ts (4)

5-5: 사용하지 않는 import 제거 필요

postCard import가 코드에서 사용되지 않습니다.

-import { postCard } from './postCard'

8-8: 주석 내용 수정 필요

주석에서 "카드 생성 모달"이라고 되어 있는데, 이 훅은 카드 수정을 위한 것입니다.

-// ✅ 카드 생성 모달에서 사용 (CreateCardForm.tsx)
+// ✅ 카드 수정 모달에서 사용 (ModifyCardForm.tsx)

21-21: 쿼리 무효화 주석 수정 필요

주석에서 'columnId' 쿼리 무효화라고 되어 있지만 실제로는 'cardId' 쿼리를 무효화하고 있습니다.

-      queryClient.invalidateQueries({ queryKey: ['cardId'] }) //'columnId' 쿼리 invalidate - 카드가 stale 상태임을 알리고 다시 fetch 하도록 유도함
+      queryClient.invalidateQueries({ queryKey: ['cardId'] }) //'cardId' 쿼리 invalidate - 카드가 stale 상태임을 알리고 다시 fetch 하도록 유도함

26-28: 에러 메시지 내용 수정 필요

에러 메시지에서 "카드 생성 실패"라고 되어 있는데, 이 훅은 카드 수정을 위한 것입니다.

-        console.error('카드 생성 실패:', message ?? '알 수 없는 에러')
+        console.error('카드 수정 실패:', message ?? '알 수 없는 에러')
      } else {
-        console.error('카드 생성 실패:', error)
+        console.error('카드 수정 실패:', error)
src/app/features/dashboard_Id/Card/cardFormModals/AssigneeList.tsx (2)

3-3: 불필요한 Avatar 컴포넌트 import 제거

Avatar 컴포넌트를 import하고 있지만 MyAssignee 컴포넌트가 아바타 렌더링을 담당하므로 사용되지 않습니다.

-import { Avatar } from '@/app/shared/components/common/Avatar'

21-21: 주석 업데이트 필요

주석에서 여전히 userId를 언급하고 있지만 실제 코드는 id를 사용합니다.

-//    - controlField.onChange(assignee.userId) 실행 → react-hook-form에 userId 값을 전달 (form 제출에는 Id 데이터만 전달함)
+//    - controlField.onChange(assignee.id) 실행 → react-hook-form에 id 값을 전달 (form 제출에는 Id 데이터만 전달함)
src/app/features/dashboard_Id/Card/Card.tsx (1)

27-27: JSON.stringify 에러 처리 추가

data-card-data 속성에서 JSON.stringify가 실패할 수 있습니다. 순환 참조나 직렬화 불가능한 값이 있을 경우를 대비해야 합니다.

-      data-card-data={JSON.stringify(card)}
+      data-card-data={(() => {
+        try {
+          return JSON.stringify(card)
+        } catch {
+          return JSON.stringify({ id: card.id, title: card.title })
+        }
+      })()}
src/app/shared/components/common/Avatar.tsx (1)

39-39: 사용자 미인증 시 조기 반환 로직 검토

props로 name과 imageUrl이 제공되어도 user가 없으면 null을 반환합니다. 이는 의도된 동작인지 확인이 필요합니다.

다음 시나리오에서 Avatar 컴포넌트가 어떻게 동작해야 하는지 명확히 하세요:

  1. 사용자가 미인증 상태이지만 명시적인 name/imageUrl props가 제공된 경우
  2. 인증된 사용자가 있고 props도 제공된 경우

만약 props가 제공되면 인증 상태와 무관하게 렌더링해야 한다면:

-  if (!user) return null // user가 없으면 렌더링하지 않음
+  if (!user && !name) return null // user와 name 모두 없으면 렌더링하지 않음
src/app/features/dashboard_Id/Card/cardFormModals/ColumnList.tsx (1)

35-35: 주석 오류 수정 필요

주석에서 "담당자 업데이트"라고 되어 있지만, 실제로는 컬럼을 업데이트하는 로직입니다.

-            setColumn(column) // 담당자 업데이트
+            setColumn(column) // 컬럼 업데이트  
src/app/features/dashboard_Id/Card/cardFormModals/ModifyCardForm.tsx (2)

81-81: 디버그 콘솔 로그 제거

개발 중 디버깅용 console.log가 남아있습니다. 프로덕션 코드에서는 제거해야 합니다.

-    console.log(tags)

121-121: 디버그 콘솔 로그 제거

프로덕션 환경에서는 불필요한 디버그 로그를 제거해야 합니다.

-    console.log('submitted', payload)
src/app/features/dashboard_Id/Card/cardModal/CardContent.tsx (2)

28-28: CSS 클래스명 오타 수정

bt-24는 유효하지 않은 Tailwind CSS 클래스로 보입니다. 아마도 mb-24 (margin-bottom)를 의도한 것 같습니다.

-      <h2 className="Text-black bt-24 text-24 font-bold">{title}</h2>
+      <h2 className="Text-black mb-24 text-24 font-bold">{title}</h2>

60-60: 디버그 콘솔 로그 제거

개발 중 디버깅용 console.log가 남아있습니다. 프로덕션 코드에서는 제거해야 합니다.

          onClick={() => {
            onClose()
-            console.log('sdfadfdsgreggsfds')
          }}
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 05d9470 and 2b003df.

⛔ Files ignored due to path filters (3)
  • public/images/arrow-dropdown.svg is excluded by !**/*.svg
  • public/images/close.svg is excluded by !**/*.svg
  • public/images/drop-more.svg is excluded by !**/*.svg
📒 Files selected for processing (24)
  • src/app/dashboard/[id]/page.tsx (3 hunks)
  • src/app/features/dashboard_Id/Card/Card.tsx (3 hunks)
  • src/app/features/dashboard_Id/Card/ColumnTitle.tsx (1 hunks)
  • src/app/features/dashboard_Id/Card/MyAssignee.tsx (1 hunks)
  • src/app/features/dashboard_Id/Card/Tags.tsx (1 hunks)
  • src/app/features/dashboard_Id/Card/TagsCanDelete.tsx (1 hunks)
  • src/app/features/dashboard_Id/Card/cardFormModals/AssigneeList.tsx (2 hunks)
  • src/app/features/dashboard_Id/Card/cardFormModals/ColumnList.tsx (1 hunks)
  • src/app/features/dashboard_Id/Card/cardFormModals/CreateCardForm.tsx (3 hunks)
  • src/app/features/dashboard_Id/Card/cardFormModals/CreateCardModal.tsx (0 hunks)
  • src/app/features/dashboard_Id/Card/cardFormModals/ModifyCardForm.tsx (1 hunks)
  • src/app/features/dashboard_Id/Card/cardFormModals/input/DateInput.tsx (1 hunks)
  • src/app/features/dashboard_Id/Card/cardModal/CardContent.tsx (1 hunks)
  • src/app/features/dashboard_Id/Card/cardModal/CardModal.tsx (1 hunks)
  • src/app/features/dashboard_Id/Column/Column.tsx (3 hunks)
  • src/app/features/dashboard_Id/api/putCard.ts (1 hunks)
  • src/app/features/dashboard_Id/api/usePutCardMutation.ts (1 hunks)
  • src/app/features/dashboard_Id/lib/getDashboardMembers.ts (1 hunks)
  • src/app/features/dashboard_Id/store/useColumnsStore.ts (1 hunks)
  • src/app/features/dashboard_Id/store/useDragStore.ts (1 hunks)
  • src/app/features/dashboard_Id/type/CardFormData.type.ts (1 hunks)
  • src/app/globals.css (3 hunks)
  • src/app/shared/components/common/Avatar.tsx (2 hunks)
  • tailwind.config.ts (1 hunks)
💤 Files with no reviewable changes (1)
  • src/app/features/dashboard_Id/Card/cardFormModals/CreateCardModal.tsx
🧰 Additional context used
🧬 Code Graph Analysis (11)
src/app/features/dashboard_Id/lib/getDashboardMembers.ts (2)
src/app/features/dashboard_Id/type/Member.type.ts (1)
  • Member (1-10)
src/app/features/dashboard_Id/type/Card.type.ts (1)
  • Assignee (1-5)
src/app/features/dashboard_Id/Card/MyAssignee.tsx (2)
src/app/features/dashboard_Id/type/Card.type.ts (1)
  • Assignee (1-5)
src/app/shared/components/common/Avatar.tsx (1)
  • Avatar (34-77)
src/app/features/dashboard_Id/api/putCard.ts (1)
src/app/features/dashboard_Id/type/CardFormData.type.ts (1)
  • CardModifyFormData (1-9)
src/app/features/dashboard_Id/api/usePutCardMutation.ts (2)
src/app/features/dashboard_Id/type/CardFormData.type.ts (1)
  • CardModifyFormData (1-9)
src/app/features/dashboard_Id/api/putCard.ts (1)
  • putCard (10-19)
src/app/features/dashboard_Id/Card/Tags.tsx (1)
src/app/features/dashboardId/Card/Tags.tsx (1)
  • Tags (3-29)
src/app/features/dashboard_Id/Card/cardFormModals/CreateCardForm.tsx (2)
src/app/shared/lib/cn.ts (1)
  • cn (4-6)
src/app/features/dashboard_Id/Card/TagsCanDelete.tsx (1)
  • TagsCanDelete (5-49)
src/app/dashboard/[id]/page.tsx (1)
src/app/features/dashboard_Id/store/useColumnsStore.ts (1)
  • useColumnsStore (14-17)
src/app/features/dashboard_Id/Card/cardFormModals/AssigneeList.tsx (1)
src/app/features/dashboard_Id/Card/MyAssignee.tsx (1)
  • MyAssignee (5-18)
src/app/features/dashboard_Id/Card/Card.tsx (4)
src/app/features/dashboard_Id/type/Card.type.ts (1)
  • Card (6-19)
src/app/shared/components/common/Avatar.tsx (1)
  • Avatar (34-77)
src/app/features/dashboard_Id/Card/cardModal/CardModal.tsx (1)
  • CardModal (6-18)
src/app/features/dashboard_Id/Card/cardModal/CardContent.tsx (1)
  • CardContent (16-91)
src/app/features/dashboard_Id/Card/cardFormModals/ColumnList.tsx (4)
src/app/features/dashboard_Id/store/useColumnsStore.ts (2)
  • SimpleColumn (3-6)
  • useColumnsStore (14-17)
src/app/features/dashboard_Id/type/CardFormData.type.ts (1)
  • CardFormData (11-13)
src/app/shared/lib/cn.ts (1)
  • cn (4-6)
src/app/features/dashboard_Id/Card/ColumnTitle.tsx (1)
  • ColumnTitle (1-10)
src/app/features/dashboard_Id/Card/cardFormModals/ModifyCardForm.tsx (13)
src/app/features/dashboard_Id/store/useColumnsStore.ts (1)
  • SimpleColumn (3-6)
src/app/features/dashboard_Id/api/useUploadCardImage.ts (1)
  • useUploadCardImage (8-19)
src/app/features/dashboard_Id/api/useMembers.ts (1)
  • useMembers (7-12)
src/app/features/dashboard_Id/type/Card.type.ts (1)
  • Assignee (1-5)
src/app/features/dashboard_Id/type/CardFormData.type.ts (2)
  • CardFormData (11-13)
  • CardModifyFormData (1-9)
src/app/features/dashboard_Id/api/usePutCardMutation.ts (1)
  • usePutCardMutation (9-32)
src/app/features/dashboard_Id/Card/cardFormModals/input/Input.tsx (1)
  • Input (9-28)
src/app/features/dashboard_Id/Card/ColumnTitle.tsx (1)
  • ColumnTitle (1-10)
src/app/shared/lib/cn.ts (1)
  • cn (4-6)
src/app/features/dashboard_Id/Card/cardFormModals/ColumnList.tsx (1)
  • ColumnList (19-44)
src/app/features/dashboard_Id/Card/MyAssignee.tsx (1)
  • MyAssignee (5-18)
src/app/features/dashboard_Id/Card/cardFormModals/AssigneeList.tsx (1)
  • AssigneeList (23-49)
src/app/features/dashboard_Id/Card/TagsCanDelete.tsx (1)
  • TagsCanDelete (5-49)
🪛 Biome (1.9.4)
src/app/features/dashboard_Id/Card/cardFormModals/ModifyCardForm.tsx

[error] 122-122: Avoid the delete operator which can impact performance.

Unsafe fix: Use an undefined assignment instead.

(lint/performance/noDelete)


[error] 126-128: Avoid the delete operator which can impact performance.

Unsafe fix: Use an undefined assignment instead.

(lint/performance/noDelete)

🔇 Additional comments (23)
src/app/features/dashboard_Id/api/putCard.ts (1)

1-3: 프로덕션용 API 클라이언트 사용 확인 필요

현재 testAxios를 사용하고 있고 정규 axios는 주석 처리되어 있습니다. 프로덕션 환경에서는 정규 API 클라이언트를 사용해야 합니다.

다음 스크립트로 다른 API 함수들에서 어떤 클라이언트를 사용하는지 확인해보세요:

#!/bin/bash
# API 함수들에서 사용되는 import 패턴 확인
rg -A 2 -B 2 "import.*from.*axios" src/app/features/dashboard_Id/api/
src/app/globals.css (4)

22-22: 다크모드 색상 업데이트 적절함

BG-white 클래스의 다크모드 배경색상이 더 어두운 톤으로 변경되어 대비가 개선되었습니다.


30-32: 새로운 유틸리티 클래스 추가 적절함

BG-lightblue 클래스가 일관된 네이밍 컨벤션을 따르며, 라이트/다크 모드를 모두 고려하여 잘 구현되었습니다.


57-59: 텍스트 색상 유틸리티 클래스 추가 적절함

Text-deepblue 클래스가 기존 색상 팔레트와 일관성을 유지하며, 접근성을 고려한 색상 조합으로 구성되었습니다.


101-101: 컴포넌트별 스타일링 분리 적절함

Input-readOnly에서 고정 너비를 제거하고 컴포넌트 레벨에서 관리하도록 변경한 것은 재사용성과 유연성을 향상시키는 좋은 접근입니다.

src/app/features/dashboard_Id/Card/cardFormModals/input/DateInput.tsx (2)

10-11: props spread 이후에 ref를 배치한 것이 좋습니다.

props가 ref를 덮어쓰는 것을 방지하기 위해 ref를 spread operator 이후에 배치한 것이 올바른 패턴입니다.


14-14: 일관된 너비 스타일링을 위한 w-520 클래스 추가가 적절합니다.

다른 폼 입력 필드들과 일관된 너비를 유지하기 위한 스타일링 개선입니다.

src/app/features/dashboard_Id/store/useColumnsStore.ts (1)

1-17: Zustand 스토어 구현이 깔끔하고 적절합니다.

SimpleColumn 인터페이스와 ColumnsStore의 구조가 명확하고, Zustand의 표준 패턴을 잘 따르고 있습니다. 카드 수정 모달에서 사용할 간소화된 컬럼 데이터 관리에 적합한 설계입니다.

src/app/features/dashboard_Id/store/useDragStore.ts (1)

3-3: 타입 파일 임포트 경로 업데이트가 적절합니다.

Card.type으로의 임포트 경로 변경이 타입 파일 네이밍 컨벤션과 일치하며, 코드베이스의 일관성을 향상시킵니다.

src/app/features/dashboard_Id/lib/getDashboardMembers.ts (3)

1-1: 타입 임포트 중앙화가 좋습니다.

로컬 Assignee 인터페이스를 제거하고 Card.type에서 임포트하는 것이 코드 일관성과 유지보수성을 향상시킵니다.


11-11: profileImageUrl 추가가 UI 개선에 도움됩니다.

MyAssignee 컴포넌트에서 아바타 표시를 위해 profileImageUrl 필드를 추가한 것이 적절합니다.


9-11: ```shell
#!/bin/bash

Member 인터페이스 확인

sed -n '1,200p' src/app/features/dashboard_Id/type/Member.type.ts

Assignee 타입 확인

sed -n '1,200p' src/app/features/dashboard_Id/type/Card.type.ts


</details>
<details>
<summary>src/app/features/dashboard_Id/Card/MyAssignee.tsx (1)</summary>

`1-18`: **MyAssignee 컴포넌트 구현이 깔끔합니다.**

담당자 정보를 아바타와 닉네임으로 표시하는 간단하고 재사용 가능한 컴포넌트입니다. Avatar 컴포넌트와의 통합도 적절하고, 스타일링도 일관성 있게 적용되었습니다.

</details>
<details>
<summary>src/app/features/dashboard_Id/Column/Column.tsx (3)</summary>

`81-82`: **스타일링 개선 승인**

기존의 하드코딩된 배경색을 `.BG-lightblue` 클래스로 변경한 것은 CSS 유틸리티 활용 측면에서 좋은 개선입니다.

---

`92-92`: **Card 컴포넌트 props 변경 승인**

전체 `column` 객체를 전달하는 것은 Card 컴포넌트가 컬럼 정보에 더 쉽게 접근할 수 있게 해주는 좋은 변경입니다.

---

`97-102`: **CreateCardModal 사용법 간소화 승인**

`onClose` prop 제거로 모달 사용법이 간소화된 것은 좋은 개선입니다.

</details>
<details>
<summary>src/app/features/dashboard_Id/type/CardFormData.type.ts (1)</summary>

`1-13`: **인터페이스 분리 리팩토링 승인**

`CardFormData`를 `CardModifyFormData`와 `CardFormData`로 분리한 것은 관심사 분리와 코드 재사용성 측면에서 훌륭한 리팩토링입니다. 카드 수정 시에는 `dashboardId`가 필요하지 않으므로 이를 분리한 것이 적절합니다.

</details>
<details>
<summary>src/app/dashboard/[id]/page.tsx (2)</summary>

`28-36`: **전역 스토어 동기화 로직 승인**

columns 데이터를 전역 스토어와 동기화하는 useEffect 구현이 적절합니다. 데이터 변환 로직과 의존성 배열 설정이 올바릅니다.

---

`144-144`: **반응형 레이아웃 개선 승인**

`mobile:flex-row`를 추가하여 모바일 환경에서의 레이아웃을 개선한 것은 좋은 UX 개선입니다.

</details>
<details>
<summary>src/app/features/dashboard_Id/Card/cardFormModals/CreateCardForm.tsx (2)</summary>

`118-132`: **드롭다운 UI 개선 승인**

담당자 입력 필드에 고정 너비 적용과 회전 애니메이션이 적용된 드롭다운 화살표 추가는 훌륭한 UX 개선입니다. `cn` 유틸리티를 활용한 조건부 스타일링도 적절합니다.

---

`221-221`: **TagsCanDelete 컴포넌트 적용 승인**

기존 `Tags` 컴포넌트를 `TagsCanDelete`로 변경하여 태그 삭제 기능을 추가한 것은 사용자 경험을 크게 향상시키는 좋은 개선입니다.

</details>
<details>
<summary>src/app/features/dashboard_Id/Card/Tags.tsx (1)</summary>

`25-28`: **다크 모드에서 텍스트 색상 대비 확인 필요**

다크 모드에서 텍스트 색상으로 `bgColors`를 사용하면 가독성 문제가 발생할 수 있습니다. 밝은 배경색이 다크 배경에서 충분한 대비를 제공하는지 확인이 필요합니다.


다음 스크립트로 색상 대비를 확인해보세요:

```shell
#!/bin/bash
# Description: 다크 모드 색상 조합의 대비 확인

echo "다크 모드 배경색들:"
echo "#774212, #366712, #711E5C, #0F3167"
echo ""
echo "텍스트로 사용되는 색상들:"
echo "#F9EEE3, #E7F7DB, #F7DBF0, #DBE6F7"
echo ""
echo "이 조합들이 WCAG 접근성 기준을 만족하는지 확인하세요."
src/app/features/dashboard_Id/Card/cardFormModals/AssigneeList.tsx (1)

38-41: 타입 정의와 필드 사용처를 정확히 확인하기 위해 아래 스크립트를 실행해 주세요.

#!/bin/bash
# CardFormData 인터페이스 확인
rg "interface CardFormData" -A 5 -g "*.ts" -g "*.tsx"

# assigneeUserId 사용처 확인
rg -C 3 "assigneeUserId" -g "*.ts" -g "*.tsx"

Comment on lines +14 to +16
const res = await api.put(
`/${process.env.NEXT_PUBLIC_TEAM_ID}/cards/${cardId}`,
payload,
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

환경변수 검증 및 오류 처리 추가 필요

환경변수가 존재하지 않을 경우에 대한 검증과 API 요청 실패에 대한 오류 처리가 필요합니다.

export async function putCard(
  payload: CardModifyFormData,
  cardId: number,
): Promise<ApiResponse> {
+  if (!process.env.NEXT_PUBLIC_TEAM_ID) {
+    throw new Error('NEXT_PUBLIC_TEAM_ID 환경변수가 설정되지 않았습니다.')
+  }
+  
+  try {
    const res = await api.put(
      `/${process.env.NEXT_PUBLIC_TEAM_ID}/cards/${cardId}`,
      payload,
    )
    return res.data
+  } catch (error) {
+    console.error('카드 수정 실패:', error)
+    throw error
+  }
}
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
const res = await api.put(
`/${process.env.NEXT_PUBLIC_TEAM_ID}/cards/${cardId}`,
payload,
export async function putCard(
payload: CardModifyFormData,
cardId: number,
): Promise<ApiResponse> {
if (!process.env.NEXT_PUBLIC_TEAM_ID) {
throw new Error('NEXT_PUBLIC_TEAM_ID 환경변수가 설정되지 않았습니다.')
}
try {
const res = await api.put(
`/${process.env.NEXT_PUBLIC_TEAM_ID}/cards/${cardId}`,
payload,
)
return res.data
} catch (error) {
console.error('카드 수정 실패:', error)
throw error
}
}
🤖 Prompt for AI Agents
In src/app/features/dashboard_Id/api/putCard.ts around lines 14 to 16, add
validation to check if the environment variable NEXT_PUBLIC_TEAM_ID is defined
before making the API call. If it is missing, throw or handle an appropriate
error. Additionally, wrap the API put request in a try-catch block to handle any
request failures and provide meaningful error handling or logging.

Comment on lines +7 to +8
const modalRoot = document.getElementById('modal-root')
if (!modalRoot) return null
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

SSR 호환성을 위한 useEffect 사용 고려

현재 구현은 클라이언트 사이드에서만 동작하며, SSR 중에는 document에 접근할 수 없어 오류가 발생할 수 있습니다.

+import { useEffect, useState } from 'react'
import { createPortal } from 'react-dom'

interface ModalProps {
  children: React.ReactNode
}
export default function CardModal({ children }: ModalProps) {
-  const modalRoot = document.getElementById('modal-root')
-  if (!modalRoot) return null
+  const [modalRoot, setModalRoot] = useState<Element | null>(null)
+  
+  useEffect(() => {
+    setModalRoot(document.getElementById('modal-root'))
+  }, [])
+
+  if (!modalRoot) return null
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
const modalRoot = document.getElementById('modal-root')
if (!modalRoot) return null
import { useEffect, useState } from 'react'
import { createPortal } from 'react-dom'
interface ModalProps {
children: React.ReactNode
}
export default function CardModal({ children }: ModalProps) {
const [modalRoot, setModalRoot] = useState<Element | null>(null)
useEffect(() => {
setModalRoot(document.getElementById('modal-root'))
}, [])
if (!modalRoot) return null
return createPortal(
children,
modalRoot
)
}
🤖 Prompt for AI Agents
In src/app/features/dashboard_Id/Card/cardModal/CardModal.tsx around lines 7 to
8, the code directly accesses document.getElementById which causes errors during
server-side rendering (SSR) because document is not defined. To fix this, move
the modalRoot assignment inside a useEffect hook and store it in a state
variable so that it only runs on the client side after the component mounts,
ensuring SSR compatibility.

Comment on lines +18 to +23
// const colorIndex = getColor(tag, bgColors.length)
// getColors함수 사용하면 NaN값이 떠서 작동을 안함.. 원래 문제 없었는데 이유를 모르겠음.
const hash = tag
.split('')
.reduce((acc, char) => acc + char.charCodeAt(0), 0)
const colorIndex = hash % 4
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

코드 중복 및 getColor 함수 문제 해결 필요

수동 해시 계산 로직이 TagsCanDelete.tsx와 중복됩니다. getColor 함수에서 NaN 문제가 발생한다면 해당 함수를 수정하는 것이 더 나은 접근입니다.

다음과 같이 개선할 수 있습니다:

-        // const colorIndex = getColor(tag, bgColors.length)
-        // getColors함수 사용하면 NaN값이 떠서 작동을 안함.. 원래 문제 없었는데 이유를 모르겠음.
-        const hash = tag
-          .split('')
-          .reduce((acc, char) => acc + char.charCodeAt(0), 0)
-        const colorIndex = hash % 4
+        const colorIndex = getColor(tag, bgColors.length)

getColor 함수의 NaN 문제를 먼저 해결하고, 공통 해시 함수를 만들어 중복을 제거하세요.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
// const colorIndex = getColor(tag, bgColors.length)
// getColors함수 사용하면 NaN값이 떠서 작동을 안함.. 원래 문제 없었는데 이유를 모르겠음.
const hash = tag
.split('')
.reduce((acc, char) => acc + char.charCodeAt(0), 0)
const colorIndex = hash % 4
const colorIndex = getColor(tag, bgColors.length)
🤖 Prompt for AI Agents
In src/app/features/dashboard_Id/Card/Tags.tsx around lines 18 to 23, the manual
hash calculation duplicates logic found in TagsCanDelete.tsx and the getColor
function currently causes NaN errors. To fix this, first debug and correct the
getColor function to prevent NaN results, then extract the hash calculation into
a shared utility function used by both components to eliminate code duplication
and ensure consistent color indexing.

Comment on lines +23 to +26
const hash = tag
.split('')
.reduce((acc, char) => acc + char.charCodeAt(0), 0)
const colorIndex = hash % 4
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

코드 중복 제거 필요

Tags.tsx와 동일한 해시 계산 로직이 중복됩니다. 공통 유틸리티 함수로 추출하세요.

공통 함수를 만들어 중복을 제거하세요:

// utils/tagColorUtils.ts
export function getTagColorIndex(tag: string): number {
  const hash = tag
    .split('')
    .reduce((acc, char) => acc + char.charCodeAt(0), 0)
  return hash % 4
}

그 후 두 컴포넌트에서 사용:

-        const hash = tag
-          .split('')
-          .reduce((acc, char) => acc + char.charCodeAt(0), 0)
-        const colorIndex = hash % 4
+        const colorIndex = getTagColorIndex(tag)
🤖 Prompt for AI Agents
In src/app/features/dashboard_Id/Card/TagsCanDelete.tsx around lines 23 to 26,
the hash calculation logic for determining colorIndex is duplicated from
Tags.tsx. Extract this logic into a shared utility function, for example
getTagColorIndex in a new file like utils/tagColorUtils.ts, which takes a tag
string and returns the color index. Then replace the duplicated code in both
components by importing and using this utility function to remove redundancy.

backgroundColor: backgroundColor,
color: textColor,
}}
onClick={() => setTags(tags.filter((t) => t !== tag))}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

키보드 접근성 개선 필요

태그 삭제가 마우스 클릭으로만 가능합니다. 키보드 접근성을 위해 Enter/Space 키 지원을 추가하세요.

           <span
             key={tag}
             className="inline-block whitespace-nowrap rounded-4 px-9 pb-3 pt-5"
+            role="button"
+            tabIndex={0}
             style={{
               backgroundColor: backgroundColor,
               color: textColor,
             }}
             onClick={() => setTags(tags.filter((t) => t !== tag))}
+            onKeyDown={(e) => {
+              if (e.key === 'Enter' || e.key === ' ') {
+                e.preventDefault()
+                setTags(tags.filter((t) => t !== tag))
+              }
+            }}
           >
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
onClick={() => setTags(tags.filter((t) => t !== tag))}
<span
key={tag}
className="inline-block whitespace-nowrap rounded-4 px-9 pb-3 pt-5"
role="button"
tabIndex={0}
style={{
backgroundColor: backgroundColor,
color: textColor,
}}
onClick={() => setTags(tags.filter((t) => t !== tag))}
onKeyDown={(e) => {
if (e.key === 'Enter' || e.key === ' ') {
e.preventDefault()
setTags(tags.filter((t) => t !== tag))
}
}}
>
{tag}
</span>
🤖 Prompt for AI Agents
In src/app/features/dashboard_Id/Card/TagsCanDelete.tsx at line 41, the tag
deletion is currently triggered only by mouse clicks via the onClick handler. To
improve keyboard accessibility, add keyboard event handling to support tag
deletion when the Enter or Space key is pressed. Implement an onKeyDown handler
that checks for these keys and triggers the same tag removal logic as the
onClick event.

Comment on lines +11 to +12
name: string
imageUrl: string | null
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

타입 정의와 런타임 로직 불일치

props가 required로 정의되어 있지만 런타임에서는 optional로 처리됩니다. 타입 정의를 실제 사용법에 맞게 수정하세요.

 type AvatarProps = {
   size?: number
-  name: string
-  imageUrl: string | null
+  name?: string
+  imageUrl?: string | null
 }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
name: string
imageUrl: string | null
type AvatarProps = {
size?: number
name?: string
imageUrl?: string | null
}
🤖 Prompt for AI Agents
In src/app/shared/components/common/Avatar.tsx around lines 11 to 12, the props
'name' and 'imageUrl' are currently defined as required in the type but are
treated as optional in the runtime logic. Update the type definitions to mark
these props as optional to match their actual usage in the component, ensuring
consistency between type definitions and runtime behavior.

Comment on lines +36 to +37
const nickname = useRef<string>()
const profileImageUrl = useRef<string | null>()
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

useRef 부적절한 사용

useRef를 단순한 값 저장용으로 사용하고 있습니다. 렌더링 간 값 유지가 필요하지 않다면 일반 변수를 사용하세요.

-  const nickname = useRef<string>()
-  const profileImageUrl = useRef<string | null>()
+  let nickname: string
+  let profileImageUrl: string | null

그리고 .current 접근을 제거:

   if (name) {
-    nickname.current = name
-    profileImageUrl.current = imageUrl
+    nickname = name
+    profileImageUrl = imageUrl
   } else {
-    nickname.current = user.nickname
-    profileImageUrl.current = user.profileImageUrl
+    nickname = user.nickname
+    profileImageUrl = user.profileImageUrl
   }
🤖 Prompt for AI Agents
In src/app/shared/components/common/Avatar.tsx at lines 36-37, useRef is used to
store simple values that do not need to persist across renders. Replace useRef
with regular variables for nickname and profileImageUrl, and remove all .current
property accesses accordingly to simplify the code and avoid misuse of useRef.

Comment on lines +114 to +116
...data,
columnId: columnId,
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

선택된 컬럼 ID 사용 로직 오류

현재 코드는 선택된 컬럼(selectedColumn)을 무시하고 기존 카드의 columnId를 사용하고 있습니다. 사용자가 다른 컬럼을 선택했을 때 해당 변경사항이 반영되지 않습니다.

    const payload: CardModifyFormData = {
      ...data,
-      columnId: columnId,
+      columnId: selectedColumn.columnId,
    }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
...data,
columnId: columnId,
}
const payload: CardModifyFormData = {
...data,
columnId: selectedColumn.columnId,
}
🤖 Prompt for AI Agents
In src/app/features/dashboard_Id/Card/cardFormModals/ModifyCardForm.tsx around
lines 114 to 116, the code incorrectly uses the existing card's columnId instead
of the selectedColumn's ID, causing changes in column selection to be ignored.
Update the code to assign columnId from the selectedColumn variable so that user
changes to the column selection are properly reflected.

Comment on lines +118 to +119
if (!data.dueDate) delete payload.dueDate
if (!data.imageUrl || !preview) delete payload.imageUrl // delete로 아예 필드의 해당 key를 지워야, 서버가 "없음"으로 인식함..
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

성능 최적화: delete 연산자 대신 undefined 할당 사용

Static analysis에서 지적한 대로 delete 연산자는 성능에 영향을 줄 수 있습니다. undefined 할당을 사용하는 것이 더 효율적입니다.

-    if (!data.dueDate) delete payload.dueDate
-    if (!data.imageUrl || !preview) delete payload.imageUrl // delete로 아예 필드의 해당 key를 지워야, 서버가 "없음"으로 인식함..
+    if (!data.dueDate) payload.dueDate = undefined
+    if (!data.imageUrl || !preview) payload.imageUrl = undefined
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
if (!data.dueDate) delete payload.dueDate
if (!data.imageUrl || !preview) delete payload.imageUrl // delete로 아예 필드의 해당 key를 지워야, 서버가 "없음"으로 인식함..
if (!data.dueDate) payload.dueDate = undefined
if (!data.imageUrl || !preview) payload.imageUrl = undefined
🤖 Prompt for AI Agents
In src/app/features/dashboard_Id/Card/cardFormModals/ModifyCardForm.tsx at lines
118-119, replace the use of the delete operator on payload keys with assigning
undefined to those keys instead, as this improves performance by avoiding the
costly delete operation while still indicating the absence of the field to the
server.

Comment on lines +65 to +76
<div>
그리드로 관리하기 / 컬럼명은 따로 컴포넌트로 만들어 빼기
<div>{column.title}</div>
<Tags tags={tags} />
<p>설명~~~~~~~~</p>
<div>
<div>{assignee.nickname}</div>
<div>{dueDate}</div>
</div>
</div>
<div> 이미지 있으면 이미지</div>
<div>댓글 컴포넌트</div>
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

개발용 플레이스홀더 코드 정리

현재 플레이스홀더 텍스트와 미완성된 구현이 포함되어 있습니다. 실제 UI 구현으로 교체하거나 TODO 주석으로 정리하는 것이 좋겠습니다.

개발 완료 후 이 섹션을 실제 컴포넌트들로 교체해야 합니다:

  • ColumnTitle 컴포넌트 사용
  • MyAssignee 컴포넌트 사용
  • 이미지 표시 로직 구현
  • 댓글 컴포넌트 구현
🤖 Prompt for AI Agents
In src/app/features/dashboard_Id/Card/cardModal/CardContent.tsx around lines 65
to 76, replace the placeholder text and incomplete UI elements with actual
components or add TODO comments. Specifically, use the ColumnTitle component for
the column title, MyAssignee component for the assignee display, implement the
image display logic if an image exists, and replace the comment placeholder with
the actual comments component. This cleanup will prepare the code for final UI
implementation.

Copy link

@Insung-Jo Insung-Jo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

구현 수고 많으셨습니다! 이제 얼마 안 남았으니 마지막까지 힘내봐용 :D

Comment on lines +7 to +8
const modalRoot = document.getElementById('modal-root')
if (!modalRoot) return null

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

코드 래빗의 리뷰 처럼 추후에 SSR 도입을 하신다면 고려할 수 있는 내용인 거 같습니다

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

넵, 제 모달에 SSR가 적합할지 나중에 한번 고민해보겠습니당

Copy link

@LeeCh0129 LeeCh0129 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

카드 수정 모달 수고많으셨습니다~ 마지막 까지 화이팅해보시죠 👍

@dkslel1225 dkslel1225 merged commit 83e718d into feature/dashboard_id Jun 20, 2025
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

✨Feat 기능 개발 🐛Fix 버그 수정

Projects

None yet

Development

Successfully merging this pull request may close these issues.

✨ Feat: 카드 수정 모달

4 participants